home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
terms
/
kermit
/
charsets
/
csetu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-01
|
8KB
|
191 lines
/*
csetu.c -- character-set utility program.
Contains three general-purpose routines, plus a main program to demonstrate
their use.
invert(): Given a translation table, compute its inverse.
compose(): Given two translation tables, compute their composition.
display(): Print a translation table in the desired radix.
F. da Cruz, Columbia University, January 1992
*/
#include <stdio.h>
char **xargv; /* Global copy of argv */
/* IBM CP437 to CP850, from CDRA */
int
x4385[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 244, 245, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 189, 156, 190, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 155, 157, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 20, 21, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
};
/* IBM CP850 to Latin Alphabet 1, from CDRA */
int
x85l1[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 28, 27, 127, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 26,
199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197,
201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 248, 163, 216, 215, 159,
225, 237, 243, 250, 241, 209, 170, 186, 191, 174, 172, 189, 188, 161, 171, 187,
155, 156, 157, 144, 151, 193, 194, 192, 169, 135, 128, 131, 133, 162, 165, 147,
148, 153, 152, 150, 145, 154, 227, 195, 132, 130, 137, 136, 134, 129, 138, 164,
240, 208, 202, 203, 200, 158, 205, 206, 207, 149, 146, 141, 140, 166, 204, 139,
211, 223, 212, 210, 245, 213, 181, 254, 222, 218, 219, 217, 253, 221, 175, 180,
173, 177, 143, 190, 182, 167, 247, 184, 176, 168, 183, 185, 179, 178, 142, 160
};
int xl185[256]; /* Latin-1 to CP850 (to be computed) */
int xl143[256]; /* Latin-1 to CP437 (to be computed) */
int x43l1[256]; /* CP437 to Latin-1 (to be computed) */
/*
Compute the inverse of a 256-byte translation table, array c1.
If the table is not invertible, print a message and exit.
If it is invertible, put the invertible table in array c2.
*/
void
invert(c1, c2) int c1[], c2[]; {
int i; /* Loop index */
int err = 0; /* Error counter */
for (i = 0; i < 256; i++) /* Initialize the output array */
c2[i] = -1; /* to all -1's. */
for (i = 0; i < 256; i++) { /* Compute the inverse. */
if (c1[i] < 0 || c1[i] > 255) { /* Check for illegal input values */
fprintf(stderr,
"Table contains illegal value %d\n",c1[i]);
exit(1);
} else if (c2[c1[i]] == -1) { /* Check for duplicates. */
c2[c1[i]] = i & 0xff; /* This one is ok. */
} else { /* Duplicate or missing values mean */
if (++err == 1) { /* character set is not invertible. */
fprintf(stderr,
"Character set not invertible.\n");
fprintf(stderr,
"The following characters appear more than once:\n");
}
fprintf(stderr, " %3d\n", i);
}
}
if (err > 0) { /* Display missing entries, if any */
fprintf(stderr,
"The following characters are missing:\n");
for (i = 0; i < 256; i++)
if (c2[i] == -1) fprintf(stderr," %3d\n", i);
exit(1);
}
}
/*
Given c1, the translation table from character set X to character set Y,
and c2, the translation table from character set Y to character set Z,
compute c3, the translation table from character set X to character set Z,
i.e. the composition of tables c1 and c2.
*/
void
compose(c1, c2, c3) int c1[], c2[], c3[]; {
int i;
for (i = 0; i < 256; i++) { /* Check for illegal input values */
if (c1[i] < 0 || c1[i] > 255 ||
c2[i] < 0 || c2[i] > 255) {
fprintf(stderr,"Table contains illegal value %d\n",c1[i]);
exit(1);
} else c3[i] = c2[c1[i]]; /* Translate c1 -> c2 -> c3 */
}
}
/*
Display character set c in the given radix (8, 10, or 16),
labeled with the given name.
*/
void
display(c,radix,name) int c[], radix; char *name; {
int i, j, k; /* Loop indices */
char buf[10]; /* Output string buffer */
printf("%s\n",name); /* Print the table name */
for (i = 0; i < 16; i++) /* Print the table, each row */
for (j = 0; j < 16; j++) { /* and each element in the row */
k = 16 * i + j; /* Table index of this item */
switch (radix) { /* Use the desired radix */
case 8: sprintf(buf, "%3o", c[k]); break; /* Octal */
case 10: sprintf(buf, "%3d", c[k]); break; /* Decimal */
case 16: sprintf(buf," %02X", c[k]); break; /* Hexadecimal */
default:
fprintf(stderr,"display: bad radix\n");
exit(1);
}
if (j == 15) /* Final item in row */
printf(k == 255 ?
"%s\n" : /* Final item in table */
"%s,\n", buf);
else
printf("%s, ",buf); /* Item within row */
}
printf("\n"); /* Blank line at end */
}
void /* Usage message */
usage(s1,s2) char *s1, *s2; {
fprintf(stderr,"%s: %s '%s'\n",xargv[0],s1,s2);
fprintf(stderr,"usage: %s [ -radix ]\n",xargv[0]);
fprintf(stderr,"optional argument is the output radix\n");
fprintf(stderr,"radix may be 8, 10, or 16, 10 by default\n");
exit(1);
}
void
main(argc,argv) int argc; char *argv[]; {
int i; /* Worker */
int r = 10; /* Radix for output, default 10 */
xargv = argv; /* Make global copy */
for (i = 1; i < argc; i++) { /* Read radix from command line */
if (*argv[i] != '-') usage("bad option",argv[i]);
r = atoi(argv[i]+1);
if (r != 8 && r != 10 && r != 16) usage("bad radix",argv[i]+1);
}
if ((i = sizeof(x4385)) != 256 * sizeof (int)) {
fprintf(stderr,"size of x4385 = %d, should be 256\n",i);
exit(1);
}
if ((i = sizeof(x85l1)) != 256 * sizeof (int)) {
fprintf(stderr,"size of x85l1 = %d, should be 256\n",i);
exit(1);
}
display(x4385,r,"CP437 to CP850"); /* These are given. */
display(x85l1,r,"CP850 to Latin-1"); /* Print them. */
invert(x85l1, xl185); /* Compute Latin-1 to cp850 */
display(xl185,r,"Latin-1 to CP850"); /* Print it. */
compose(x4385, x85l1, x43l1); /* Compute cp437-to-latin1 */
display(x43l1,r,"CP437 to Latin-1"); /* Print it. */
invert(x43l1, xl143); /* Compute Latin1 to CP437 */
display(xl143,r,"Latin-1 to CP437"); /* Print it. */
}